<?php

class Detalle
{
    private $rfc;
    private $monto;
    private $cuenta;
    private $descripcion;
    private $fecha;
    private $detalle;

    public function __construct($rfc, $descripcion, $cuenta, $monto, $fecha) {
        $this->rfc = mb_strtoupper(trim($rfc));
        $this->descripcion = mb_strtoupper(trim($descripcion));
        $this->cuenta = trim($cuenta);
        $this->monto = trim($monto);
        $this->fecha = $fecha;
        $this->detalle = null;
    }

    public function getString() {
        if ($this->detalle === null) {
            $parts = array();
            $parts[] = 'D'; // Detalle
            $parts[] = $this->fecha;
            $parts[] = $this->getFiller(10);
            $parts[] = $this->getRFC();
            $parts[] = $this->getDescripcion();
            $parts[] = $this->getMonto();
            $parts[] = '072'; // Banco al que pertenece la cuenta de cargo
            $parts[] = '01'; // 01= Cuentas Banorte, 03=Tarjeta de Débito Banorte o de otros bancos   40=CCC ó CLABE Banorte o de otros bancos
            $parts[] = $this->getCuenta();
            $parts[] = '1'; //"1.- Alta Factura, 2.- Baja de Factura, 3.- Solicitud de verificación de Cuentas"
            $parts[] = 'A'; // A=Alta, B=Baja solo el primer nivel es decir, sobre lo enviado durante el día
            $parts[] = '00000000'; // IVA de la factura 8 lugares
            $parts[] = $this->getFiller(18);
            $this->detalle = implode('', $parts);
        }
        return $this->detalle;
    }

    private function getDescripcion() {
        $descripcion = $this->descripcion;
        $descripcionSinAcentos = str_replace(array('Á', 'É', 'Í', 'Ó', 'Ú', 'Ñ'), array(
            'A', 'E', 'I', 'O', 'U', 'N'), $descripcion);
        return str_pad($descripcionSinAcentos, 40);
    }

    private function getRFC() {
        $rfc = $this->rfc;
        return str_pad($rfc, 40);
    }

    private function getMonto() {
        if ($this->monto <= 0) {
            throw new Exception('Monto máximo a CERO');
        }
        $monto = number_format($this->monto, 2, '', '');
        return str_pad($monto, 15, '0', STR_PAD_LEFT);
    }

    private function getCuenta() {
        $cuenta = $this->cuenta;
        return str_pad($cuenta, 18, '0', STR_PAD_LEFT);
    }

    private function getFiller($num) {
        return str_pad('', $num);
    }

}
